home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
tiff
/
tif_open.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-21
|
9KB
|
373 lines
/* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_open.c,v 1.47 1994/09/17 23:22:37 sam Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 Sam Leffler
* Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
/*
* TIFF Library.
*/
#include "tiffiop.h"
static const long typemask[13] = {
0L, /* TIFF_NOTYPE */
0x000000ffL, /* TIFF_BYTE */
0xffffffffL, /* TIFF_ASCII */
0x0000ffffL, /* TIFF_SHORT */
0xffffffffL, /* TIFF_LONG */
0xffffffffL, /* TIFF_RATIONAL */
0x000000ffL, /* TIFF_SBYTE */
0x000000ffL, /* TIFF_UNDEFINED */
0x0000ffffL, /* TIFF_SSHORT */
0xffffffffL, /* TIFF_SLONG */
0xffffffffL, /* TIFF_SRATIONAL */
0xffffffffL, /* TIFF_FLOAT */
0xffffffffL, /* TIFF_DOUBLE */
};
static const int bigTypeshift[13] = {
0, /* TIFF_NOTYPE */
24, /* TIFF_BYTE */
0, /* TIFF_ASCII */
16, /* TIFF_SHORT */
0, /* TIFF_LONG */
0, /* TIFF_RATIONAL */
16, /* TIFF_SBYTE */
16, /* TIFF_UNDEFINED */
24, /* TIFF_SSHORT */
0, /* TIFF_SLONG */
0, /* TIFF_SRATIONAL */
0, /* TIFF_FLOAT */
0, /* TIFF_DOUBLE */
};
static const int litTypeshift[13] = {
0, /* TIFF_NOTYPE */
0, /* TIFF_BYTE */
0, /* TIFF_ASCII */
0, /* TIFF_SHORT */
0, /* TIFF_LONG */
0, /* TIFF_RATIONAL */
0, /* TIFF_SBYTE */
0, /* TIFF_UNDEFINED */
0, /* TIFF_SSHORT */
0, /* TIFF_SLONG */
0, /* TIFF_SRATIONAL */
0, /* TIFF_FLOAT */
0, /* TIFF_DOUBLE */
};
/*
* Initialize the bit fill order, the
* shift & mask tables, and the byte
* swapping state according to the file
* contents and the machine architecture.
*/
static void
TIFFInitOrder(register TIFF* tif, int magic, int bigendian)
{
/* XXX how can we deduce this dynamically? */
tif->tif_fillorder = FILLORDER_MSB2LSB;
tif->tif_typemask = typemask;
if (magic == TIFF_BIGENDIAN) {
tif->tif_typeshift = bigTypeshift;
if (!bigendian)
tif->tif_flags |= TIFF_SWAB;
} else {
tif->tif_typeshift = litTypeshift;
if (bigendian)
tif->tif_flags |= TIFF_SWAB;
}
}
int
_TIFFgetMode(const char* mode, const char* module)
{
int m = -1;
switch (mode[0]) {
case 'r':
m = O_RDONLY;
if (mode[1] == '+')
m = O_RDWR;
break;
case 'w':
case 'a':
m = O_RDWR|O_CREAT;
if (mode[0] == 'w')
m |= O_TRUNC;
break;
default:
TIFFError(module, "\"%s\": Bad mode", mode);
break;
}
return (m);
}
TIFF*
TIFFClientOpen(
const char* name, const char* mode,
thandle_t clientdata,
TIFFReadWriteProc readproc,
TIFFReadWriteProc writeproc,
TIFFSeekProc seekproc,
TIFFCloseProc closeproc,
TIFFSizeProc sizeproc,
TIFFMapFileProc mapproc,
TIFFUnmapFileProc unmapproc
)
{
static const char module[] = "TIFFClientOpen";
TIFF *tif;
int m, bigendian;
m = _TIFFgetMode(mode, module);
if (m == -1)
goto bad2;
tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1);
if (tif == NULL) {
TIFFError(module, "%s: Out of memory (TIFF structure)", name);
goto bad2;
}
_TIFFmemset(tif, 0, sizeof (*tif));
tif->tif_name = (char *)tif + sizeof (TIFF);
strcpy(tif->tif_name, name);
tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
tif->tif_curdir = (tdir_t) -1; /* non-existent directory */
tif->tif_curoff = 0;
tif->tif_curstrip = (tstrip_t) -1; /* invalid strip */
tif->tif_row = (uint32)-1; /* read/write pre-increment */
tif->tif_clientdata = clientdata;
tif->tif_readproc = readproc;
tif->tif_writeproc = writeproc;
tif->tif_seekproc = seekproc;
tif->tif_closeproc = closeproc;
tif->tif_sizeproc = sizeproc;
tif->tif_mapproc = mapproc;
tif->tif_unmapproc = unmapproc;
{ int one = 1; char* cp = (char*)&one; bigendian = (*cp == 0); }
/*
* Read in TIFF header.
*/
if (!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
if (tif->tif_mode == O_RDONLY) {
TIFFError(name, "Cannot read TIFF header");
goto bad;
}
/*
* Setup header and write.
*/
tif->tif_header.tiff_magic = bigendian ?
TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
tif->tif_header.tiff_version = TIFF_VERSION;
tif->tif_header.tiff_diroff = 0; /* filled in later */
if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
TIFFError(name, "Error writing TIFF header");
goto bad;
}
/*
* Setup the byte order handling.
*/
TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
/*
* Setup default directory.
*/
if (!TIFFDefaultDirectory(tif))
goto bad;
tif->tif_diroff = 0;
return (tif);
}
/*
* Setup the byte order handling.
*/
if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN) {
TIFFError(name, "Not a TIFF file, bad magic number %d (0x%x)",
tif->tif_header.tiff_magic,
tif->tif_header.tiff_magic);
goto bad;
}
TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
/*
* Swap header if required.
*/
if (tif->tif_flags & TIFF_SWAB) {
TIFFSwabShort(&tif->tif_header.tiff_version);
TIFFSwabLong(&tif->tif_header.tiff_diroff);
}
/*
* Now check version (if needed, it's been byte-swapped).
* Note that this isn't actually a version number, it's a
* magic number that doesn't change (stupid).
*/
if (tif->tif_header.tiff_version != TIFF_VERSION) {
TIFFError(name,
"Not a TIFF file, bad version number %d (0x%x)",
tif->tif_header.tiff_version,
tif->tif_header.tiff_version);
goto bad;
}
tif->tif_flags |= TIFF_MYBUFFER;
tif->tif_rawcp = tif->tif_rawdata = 0;
tif->tif_rawdatasize = 0;
/*
* Setup initial directory.
*/
switch (mode[0]) {
case 'r':
tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
if (TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size))
tif->tif_flags |= TIFF_MAPPED;
if (TIFFReadDirectory(tif)) {
tif->tif_rawcc = -1;
tif->tif_flags |= TIFF_BUFFERSETUP;
return (tif);
}
break;
case 'a':
/*
* Don't append to file that has information
* byte swapped -- we will write data that is
* in the opposite order.
*/
if (tif->tif_flags & TIFF_SWAB) {
TIFFError(name,
"Cannot append to file that has opposite byte ordering");
goto bad;
}
/*
* New directories are automatically append
* to the end of the directory chain when they
* are written out (see TIFFWriteDirectory).
*/
if (!TIFFDefaultDirectory(tif))
goto bad;
return (tif);
}
bad:
tif->tif_mode = O_RDONLY; /* XXX avoid flush */
TIFFClose(tif);
return ((TIFF*)0);
bad2:
(void) (*closeproc)(clientdata);
return ((TIFF*)0);
}
tsize_t
TIFFScanlineSize(TIFF* tif)
{
TIFFDirectory *td = &tif->tif_dir;
tsize_t scanline;
scanline = td->td_bitspersample * td->td_imagewidth;
if (td->td_planarconfig == PLANARCONFIG_CONTIG)
scanline *= td->td_samplesperpixel;
return (howmany(scanline, 8));
}
/*
* Query functions to access private data.
*/
/*
* Return open file's name.
*/
const char *
TIFFFileName(TIFF* tif)
{
return (tif->tif_name);
}
/*
* Return open file's I/O descriptor.
*/
int
TIFFFileno(TIFF* tif)
{
return (tif->tif_fd);
}
/*
* Return read/write mode.
*/
int
TIFFGetMode(TIFF* tif)
{
return (tif->tif_mode);
}
/*
* Return nonzero if file is organized in
* tiles; zero if organized as strips.
*/
int
TIFFIsTiled(TIFF* tif)
{
return (isTiled(tif));
}
/*
* Return current row being read/written.
*/
uint32
TIFFCurrentRow(TIFF* tif)
{
return (tif->tif_row);
}
/*
* Return index of the current directory.
*/
tdir_t
TIFFCurrentDirectory(TIFF* tif)
{
return (tif->tif_curdir);
}
/*
* Return current strip.
*/
tstrip_t
TIFFCurrentStrip(TIFF* tif)
{
return (tif->tif_curstrip);
}
/*
* Return current tile.
*/
ttile_t
TIFFCurrentTile(TIFF* tif)
{
return (tif->tif_curtile);
}
/*
* Return nonzero if the file has byte-swapped data.
*/
int
TIFFIsByteSwapped(TIFF* tif)
{
return ((tif->tif_flags & TIFF_SWAB) != 0);
}